package com.pe.pgn.clubpgn.webapp.controller.canje;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;

import com.pe.pgn.clubpgn.common.CLPConstantes;
import com.pe.pgn.clubpgn.domain.ClpbCategoria;
import com.pe.pgn.clubpgn.domain.ClpbEstacion;
import com.pe.pgn.clubpgn.domain.ClpmSerieCanje;
import com.pe.pgn.clubpgn.domain.beans.BNAlmacen;
import com.pe.pgn.clubpgn.domain.beans.BNArticulo;
import com.pe.pgn.clubpgn.domain.beans.BNCatalogo;
import com.pe.pgn.clubpgn.domain.beans.BNDocumentoDetalle;
import com.pe.pgn.clubpgn.domain.beans.BNDocumentoMovArticulo;
import com.pe.pgn.clubpgn.domain.beans.BNEstacion;
import com.pe.pgn.clubpgn.model.User;
import com.pe.pgn.clubpgn.service.CanjeService;
import com.pe.pgn.clubpgn.service.CatalogoService;
import com.pe.pgn.clubpgn.service.CategoriaService;
import com.pe.pgn.clubpgn.service.DevolucionClienteService;
import com.pe.pgn.clubpgn.service.EstacionService;
import com.pe.pgn.clubpgn.webapp.controller.BaseFormController;
import com.pe.pgn.clubpgn.webapp.util.CalendarUtil;
import com.pe.pgn.clubpgn.webapp.util.ValidationUtil;

/**
 * @author Frank
 * */

@Controller
@RequestMapping("/canje/**")
public class CanjeController extends BaseFormController{
	
	@Autowired
	private CanjeService canjeService;
	
	@Autowired
	private CategoriaService categoriaService;
	
	@Autowired
	private EstacionService estacionService;
	
	@Autowired
	private CatalogoService catalogoService;
	
	@Autowired
	private DevolucionClienteService devClienteService;
	
	@RequestMapping(value = "/canjelist.html")
    public @ModelAttribute("canjeform") BNDocumentoMovArticulo listarCanjes(
    	@ModelAttribute("canjeform") BNDocumentoMovArticulo bndocumento, 
    	@RequestParam(value = "search", required = false) String search, Model model) {

		User beanUser = canjeService.getUsuarioLogueado();
		ClpbEstacion estacion = beanUser.getClpbEstacion();
		
		//si el usuario logueado no tiene una estacion relacionada
		if(estacion != null){
			model.addAttribute("coEstacionUsuario", estacion.getId());
		}else{
			model.addAttribute("coEstacionUsuario", "-1");
		}
		
		if(StringUtils.isBlank(search)){
			List<BNDocumentoMovArticulo> canjes  = canjeService.obtenerListaCanje();
			model.addAttribute("listacanjes", canjes);
		}else{
	
			List<BNDocumentoMovArticulo> canjes = canjeService.busquedaCanje(bndocumento.getCodeEstacion(),bndocumento.getCodTarjeta(),
						bndocumento.getInicioDocumento(),bndocumento.getFinDocumento(),bndocumento.getCoCatalogo(),bndocumento.getNuSerie(),
						bndocumento.getNuDocumento(),bndocumento.getDeCliente(),bndocumento.getCoCodigoPremio(),bndocumento.getStCanje(),
						bndocumento.getStTipoDoc());
			
			model.addAttribute("listacanjes", canjes);
		}		
				
		List<ClpmSerieCanje> serieCanje = new ArrayList<ClpmSerieCanje>();
		List<BNEstacion> estaciones = estacionService.obtenerTodoEstaciones();		
		List<BNCatalogo> catalogos 	= catalogoService.obtenerTodoCatalogos(false);	
		
		model.addAttribute("estaciones" , estaciones);
		model.addAttribute("catalogos"  , catalogos);
		model.addAttribute("seriecanje" , serieCanje);
		model.addAttribute("date_format", CLPConstantes.DATE_PATTERN);
		
		return bndocumento;
    }
	
	
	@RequestMapping(value = "/canjeform.html", method = RequestMethod.GET)
	public @ModelAttribute("canjeform") BNDocumentoMovArticulo verCanjePremio(
		   @RequestParam(value = "id", required = false) Long id, 
		   @RequestParam(value = "codCanje", required = false) Long codCanje, 
		   Model model) {

		BNDocumentoMovArticulo bnCanje  = new BNDocumentoMovArticulo();
		User beanUser = canjeService.getUsuarioLogueado();
		ClpbEstacion estacion = beanUser.getClpbEstacion();
		
		if (id != null) { 
			//modo update
			if(codCanje!=null){
				bnCanje=canjeService.obtenerCanjesInstantaneo(id+"", codCanje+"");
				bnCanje.setId(id);
			}else{
				bnCanje = canjeService.obtenerCanjePremio(id);
				List<BNDocumentoDetalle> listaDevueltos = devClienteService.obtenerListaDevueltos(bnCanje.getId());		
				model.addAttribute("devueltosSinSerie", listaDevueltos.size());	 			
				bnCanje.setDevueltos(Long.valueOf(listaDevueltos.size()));
				bnCanje.setCodCanje(null);
			}
		}else{ //modo insert
			
			List<BNAlmacen> listaalmacen	= new ArrayList<BNAlmacen>();
			List<ClpmSerieCanje> serieCanje = new ArrayList<ClpmSerieCanje>();
			
			canjeService.obtenerListasDatosUbigeo(model,bnCanje);
			bnCanje.setVaCantidad(1L);
			bnCanje.setStIndicatorFirst("Y");
			bnCanje.setStTipoDocSerie(CLPConstantes.ST_DOCUMENTO_CANJE);
			bnCanje.setDaFechaDocumento(CalendarUtil.calendarToString
			(CLPConstantes.DATE_PATTERN, Calendar.getInstance())); //seteando la fecha Actual
			
			if(estacion == null){ //si el usuario logueado no tiene una estacion relacionada
				
				listaalmacen = canjeService.obtenerListaAlmacen();
				if(ValidationUtil.validateList(listaalmacen)){
					BNAlmacen bean = listaalmacen.get(0);
					serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento(
					bean.getCoEstacion().toString(), CLPConstantes.ST_DOCUMENTO_CANJE);
				}else{
					serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento("-2","-2");
				}
				
			}else{
				BNAlmacen bnalmacen = canjeService.obtenerAlmacenPorEstacion(estacion.getId());
				if(bnalmacen != null){
					
					bnCanje.setCoAlmacen(bnalmacen.getId().toString());
					bnCanje.setDeAlmacen(bnalmacen.getDeAlmacen());
					
					serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento(
					estacion.getId().toString(), CLPConstantes.ST_DOCUMENTO_CANJE);
					
				}else{
					
					listaalmacen = canjeService.obtenerListaAlmacen();
					if(ValidationUtil.validateList(listaalmacen)){
						BNAlmacen bean = listaalmacen.get(0);
						serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento(
						bean.getCoEstacion().toString(), CLPConstantes.ST_DOCUMENTO_CANJE);
					}else{
						serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento("-2","-2");
					}
				}
			}
			model.addAttribute("seriecanje"   	   , serieCanje);
			model.addAttribute("listaalmacen" 	   , listaalmacen);	
		}	
		model.addAttribute("canjeform" , bnCanje);
		return bnCanje;
	}


	@RequestMapping(value = "/buscarpremios.html", method = RequestMethod.GET)
	public String  buscarPremios(
	@RequestParam(value = "coalmacen", required = false) Long coalmacen,
	@RequestParam(value = "coestacion", required = false) Long coestacion,
	Model model) {
		
		if(coestacion != null && coalmacen == null){
			
			BNAlmacen bnalmacen = canjeService.
			obtenerAlmacenPorEstacion(coestacion);				
			
			if(bnalmacen != null){
				coalmacen = bnalmacen.getId();
			}else{
				coalmacen = new Long("-1"); //quiere decir que la estacion no tiene relacionado un almacen
			}			
		}		
	
		Long coCatalogo = null;
		List<BNCatalogo> catalogos = catalogoService.obtenerTodoCatalogos(false);
		if(!catalogos.isEmpty()){
			BNCatalogo beancat = (BNCatalogo)catalogos.get(0);
			coCatalogo = beancat.getId();
		}else{
			BNCatalogo bncatalogo = new BNCatalogo();
			bncatalogo.setId(new Long("-1"));
			bncatalogo.setDeCatalogo("----");
			catalogos.add(bncatalogo);		
		}
		
		List<BNArticulo> listapremios   = canjeService.obtenerPremios(coalmacen,coCatalogo);
		List<ClpbCategoria> categorias 	= categoriaService.obtenerTodoCategorias();		
	
		model.addAttribute("coalmacen"	 , coalmacen);
		model.addAttribute("listapremios", listapremios);
		model.addAttribute("categorias"  , categorias);
		model.addAttribute("catalogos"   , catalogos);
		return "/wizard/premiowizardform";
	}
	
	
	@RequestMapping(value = "/canjeform.html", method = RequestMethod.POST)
	public String manager(@ModelAttribute("canjeform") BNDocumentoMovArticulo bndocumento,
		BindingResult result, SessionStatus status, HttpServletRequest request, Model model) {
		
		String typeOperationDocument = request.getParameter("typeOperationDocument");
		String coDepartamento = request.getParameter("coDepartamentoHDN");
		String coProvincia = request.getParameter("coProvinciaHDN");
		String coDistrito = request.getParameter("coDistritoHDN");
		
		bndocumento.setCoDepartamento(coDepartamento);
		bndocumento.setCoProvincia(coProvincia);
		bndocumento.setCoDistrito(coDistrito);
		
		if ("RS".equalsIgnoreCase(typeOperationDocument)) {
			return reservarDocumentoCanje(bndocumento, result, status, request, model);
		}
		else if ("CJ".equalsIgnoreCase(typeOperationDocument)) {
			return canjearPremio(bndocumento, result, status, request, model);
		}
		else{
			return null;
		}
	}
	
	
	@SuppressWarnings("rawtypes")
	public String canjearPremio(BNDocumentoMovArticulo bndocumento,
	BindingResult result, SessionStatus status, HttpServletRequest request, Model model) {
		
    	String stManejaStockPuntoCanje = bndocumento.getStManejaStockPuntoCanje();
    	if(CLPConstantes.ST_VERDADERO.equalsIgnoreCase(stManejaStockPuntoCanje)){ //CANJE - PUNTO DE CANJE 
	    	
    		
			Map map = canjeService.guardarCanjePremio(bndocumento);
	    	if(map.get("msg").equals("success")){
	    		saveMessage(request, getText("canjeForm.added", request.getLocale()));
	    		Long id = (Long)map.get("id");
	    		return "redirect:canjeform.html?id="+id+"&amp;from=list";
	    	}else{
	    		
	    		String strDetalle = String.valueOf(map.get("detalle"));
	    		if(strDetalle.equalsIgnoreCase("coCodigoPremio")){
	    			saveError(request, getText("canjeForm.codigopremio.invalido.almacen", request.getLocale()));
	    		}else if(strDetalle.equalsIgnoreCase("codTarjeta")){
	    			saveError(request, getText("canjeForm.codigotarjeta.invalido", request.getLocale()));
	    		}else if(strDetalle.equalsIgnoreCase("vaCantidad")){
	    			saveError(request, getText("canjeForm.vacantidad.excesiva", map.get("flag").toString(), request.getLocale()));
	    		}else if(strDetalle.equalsIgnoreCase("listDocumentoDetalle")){
	    			saveError(request, getText("canjeForm.listadetalle.obligatoria", request.getLocale()));
	    		}else if(strDetalle.equalsIgnoreCase("dePuntosAcumulados")){
	    			saveError(request, getText("canjeForm.puntos.insuficientes", request.getLocale()));
	    		}else{
	    			saveError(request, getText("errors.general", request.getLocale()));
	    		}
	    		
	    		List<BNAlmacen> listaalmacen	= new ArrayList<BNAlmacen>();
	        	List<ClpmSerieCanje> serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento("-2", "-2");
	        	
	        	canjeService.obtenerListasDatosUbigeo(model,bndocumento);
	        	bndocumento.setStTipoDocSerie(CLPConstantes.ST_DOCUMENTO_CANJE);
	        	
	        	if(StringUtils.isBlank(bndocumento.getDeAlmacen())){
	        		
	        		listaalmacen = canjeService.obtenerListaAlmacen();	        		
	        		if(ValidationUtil.validateList(listaalmacen)){
	        			BNAlmacen bean = listaalmacen.get(0);
	        			serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento(
	        			bean.getCoEstacion().toString(), CLPConstantes.ST_DOCUMENTO_CANJE);
	        		}
	            }
	        	
	        	model.addAttribute("seriecanje"   	   , serieCanje);
	    		model.addAttribute("listaalmacen" 	   , listaalmacen);	
	        	model.addAttribute("canjeform" 		   , bndocumento);
	    		return "/canje/canjeform";
	    	}
    	}else{ //CANJE - DESPUES DE UNA RESERVA
    		
    		Map map = canjeService.canjearReserva(bndocumento);
	    	if(map.get("msg").equals("success")){
	    	
	    		saveMessage(request, getText("canjeForm.added", request.getLocale()));
	    		return "redirect:canjeform.html?id="+bndocumento.getId()+"&amp;from=list";
	    	
	    	}else if(map.get("dtl") != null){
	    		saveError(request, map.get("dtl").toString());
	    		return "redirect:canjeform.html?id="+bndocumento.getId()+"&amp;from=list";
	    	}else{
	    		saveError(request, getText("errors.general", request.getLocale()));
	    		return "redirect:canjeform.html?id="+bndocumento.getId()+"&amp;from=list";
	    	}
    	}
	}
	
    
	@SuppressWarnings("rawtypes")
	public String reservarDocumentoCanje(BNDocumentoMovArticulo bndocumento,
	BindingResult result, SessionStatus status, HttpServletRequest request, Model model) {
		
    	Map map = canjeService.guardarCanjePremio(bndocumento);
    	if(map.get("msg").equals("success")){
    		saveMessage(request, getText("canjeForm.reserve.added", request.getLocale()));
    		Long id = (Long)map.get("id");
    		return "redirect:canjeform.html?id="+id+"&amp;from=list";
    	}else{
    		
    		String strDetalle = String.valueOf(map.get("detalle"));
    		if(strDetalle.equalsIgnoreCase("coCodigoPremio")){
    			saveError(request, getText("canjeForm.codigopremio.invalido.almacen", request.getLocale()));
    		}else if(strDetalle.equalsIgnoreCase("codTarjeta")){
    			saveError(request, getText("canjeForm.codigotarjeta.invalido", request.getLocale()));
    		}else if(strDetalle.equalsIgnoreCase("vaCantidad")){
    			saveError(request, getText("canjeForm.vacantidad.excesiva", map.get("flag").toString(), request.getLocale()));
    		}else if(strDetalle.equalsIgnoreCase("listDocumentoDetalle")){
    			saveError(request, getText("canjeForm.listadetalle.obligatoria", request.getLocale()));
    		}else if(strDetalle.equalsIgnoreCase("dePuntosAcumulados")){
    			saveError(request, getText("canjeForm.puntos.insuficientes", request.getLocale()));
    		}else{
    			saveError(request, getText("errors.general", request.getLocale()));
    		}
    		
    		List<BNAlmacen> listaalmacen	= new ArrayList<BNAlmacen>();
    		List<ClpmSerieCanje> serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento("-2", "-2");
        	
    		canjeService.obtenerListasDatosUbigeo(model,bndocumento);
    		bndocumento.setStTipoDocSerie(CLPConstantes.ST_DOCUMENTO_RESERVA);
        	
        	if(StringUtils.isBlank(bndocumento.getDeAlmacen())){
        		
        		listaalmacen = canjeService.obtenerListaAlmacen();
        		if(ValidationUtil.validateList(listaalmacen)){
        			BNAlmacen bean = listaalmacen.get(0);
        			serieCanje = canjeService.obtenerListaSerieCanjePorEstacionTipoDocumento(
        			bean.getCoEstacion().toString(), CLPConstantes.ST_DOCUMENTO_RESERVA);
        		}
        	}  	
        	
        	model.addAttribute("seriecanje"   	   , serieCanje);
    		model.addAttribute("listaalmacen" 	   , listaalmacen);	
        	model.addAttribute("canjeform" 		   , bndocumento);
    		return "/canje/canjeform";
    	}
	}
	
	@RequestMapping(value = "/ticketcanjeform.html", method = RequestMethod.GET)
	public void verCanjePremio(
		   @RequestParam(value = "id", required = false) Long id, 
		   @RequestParam(value = "codCanje", required = false) Long codCanje,
		   HttpServletResponse response) {

		try{
			BNDocumentoMovArticulo bnCanje  = new BNDocumentoMovArticulo();
			if(codCanje!=null){
				bnCanje=canjeService.obtenerCanjesInstantaneo(id+"", codCanje+"");
				bnCanje.setDaFechaDocumento(bnCanje.getDaFechaCanje());
			}else{
				bnCanje = canjeService.obtenerCanjePremio(id);
				List<BNDocumentoDetalle> listaDevueltos = devClienteService.obtenerListaDevueltos(bnCanje.getId());		
				bnCanje.setDevueltos(Long.valueOf(listaDevueltos.size()));
				bnCanje.setCodCanje(null);
			}
			
			ByteArrayOutputStream baos = TicketPdfUtil.createPdf(bnCanje);
			
			response.setHeader("Expires", "0");
			response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
			response.setHeader("Content-Disposition", "attachment; filename=\"TicketCanje.pdf\"");
			response.setContentType("application/pdf");
			response.setContentLength(baos.size());
			OutputStream os = response.getOutputStream();
			baos.writeTo(os);
			os.flush();
			os.close();
		
		}
		catch(Exception e) {
			log.info(e.getMessage());
		}
	}
}
